from enum import StrEnum
from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import func
from core.file.helpers import get_signed_file_url
from models.engine import db
from models.types import StringUUID

class FVerTaskStatus(StrEnum):
    PENDING = "P"
    UPDATING = "U"
    SUCCESS = "S"
    FAILED = "F"
    STOP = "T"
    @staticmethod
    def choices()->list[str]:
        return ['P','U','S','F','T']

class RobHardwareVersion(db.Model):
    __tablename__ = "rob_hver"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='rob_hver_pk'),
        db.Index('idx_rob_hver_tenant', 'tenant_id'),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False)
    ver = db.Column(db.String(128), nullable=False, comment="版本号")
    descrip = db.Column(db.String(512), nullable=False, comment="说明描述")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)

    # @property
    # def emoji_packs(self) -> list[RobEmojiPack]:
    #     return db.session.query(RobEmojiPack).join(RobEmoPackHVERMap, RobEmoPackHVERMap.pack_id == RobEmojiPack.id).filter(RobEmoPackHVERMap.hver == self.ver).all()

    # @property
    # def timbres(self)->list[RobTimbre]:
    #     return db.session.query(RobTimbre).join(RobTimbreHVERMap, RobTimbreHVERMap.timbre_id == RobTimbre.id).filter(RobTimbreHVERMap.hver==self.ver).all()
    

class RobFirewareVersion(db.Model):
    __tablename__ = "rob_fver"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='rob_fver_pk'),
        db.Index('idx_rob_fver_tenant', 'tenant_id'),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False)
    ver = db.Column(db.String(128), nullable=False, comment="版本号")
    
    md5 = db.Column(db.String(256), nullable=True, comment="MD5")
    file_id = db.Column(StringUUID, nullable=True, comment="文件ID")
    file_url = db.Column(db.String(512), nullable=True, comment="文件URL")
    agent_type = db.Column(db.String(32), nullable=False, comment="精灵类型")
    is_new = db.Column(db.Boolean, nullable=False, comment="是否最新")
    descrip = db.Column(db.String(512), nullable=False, comment="说明描述")
    # is_force = db.Column(db.Boolean, nullable=False,server_default=db.text("true"),
    #                      default=True, comment="是否强制更新")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)

    @property
    def url(self)->str|None:
        if self.file_id:
            return get_signed_file_url(self.file_id)
        elif self.file_url:
            return self.file_url
        return None


class FVerTaskResult(db.Model):
    __tablename__ = "fver_task_result"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='fver_task_result_pk'),
        db.Index('idx_fver_task_result_task', 'task_id'),
    )
    id = db.Column(db.BigInteger, primary_key=True,autoincrement=True, comment="任务结果ID",server_default=db.text('nextval(\'fver_task_result_id_seq\'::regclass)'))
    task_id = db.Column(StringUUID, nullable=False, comment="任务ID")
    new_ver = db.Column(db.String(32), nullable=True, comment="新版本")
    robot_id = db.Column(db.String(64), nullable=False, comment="机器人ID")
    status = db.Column(db.String(1), nullable=False,server_default=db.text("'P'"), comment="状态")
    pushed_at = db.Column(db.DateTime, nullable=True, comment="推送时间")
    update_at = db.Column(db.DateTime, nullable=True, comment="更新时间")
    updated_at = db.Column(db.DateTime, nullable=True, comment="更新时间")
    last_state_at = db.Column(db.DateTime, nullable=True, comment="最后状态更新时间")
    

class FVerTask(db.Model):
    __tablename__="fver_task"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='fver_task_pk'),
        db.Index('idx_fver_task_fver', 'fver_id'),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    name = db.Column(db.String(128), nullable=False, comment="任务名称")
    fver_id = db.Column(StringUUID, nullable=False, comment="版本ID")
    reservation_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp(), comment="预约时间")
    remark = db.Column(db.String(512), nullable=True, comment="备注")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True, comment="更新时间")
    updated_by = db.Column(StringUUID, nullable=True, comment="更新人")
    is_deleted = db.Column(db.Boolean, nullable=False, default=False, comment="是否删除")

    @property
    def results(self)->list[FVerTaskResult]:
        return db.session.query(FVerTaskResult).filter(FVerTaskResult.task_id == self.id).all()
    
    @property
    def robot_count(self)->int:
        return db.session.query(FVerTaskResult).filter(FVerTaskResult.task_id == self.id).count()